﻿using System;
using System.Collections.Generic;
using System.Data;
using System.Linq;
using System.Text;
using BLToolkit.Data;
using Devsoft.DB.Models;

namespace Devsoft.DB.Models
{
    public class Transaction
    {
        const IsolationLevel defaultLevel = IsolationLevel.ReadCommitted;
        public static Transaction Current
        {
            get
            {
                return new Transaction(DataContextFactory.GetScopedDataContext<DbManager>((Type)null));
            }
        }


        public static Transaction Begin(IsolationLevel level = defaultLevel)
        {
            var transaction = Current;
            transaction.Enter(level);
            return transaction;
        }
        
        public static void AutoCommit(Action action, IsolationLevel level = defaultLevel)
        {
            var transaction = Current;
            transaction.Enter();
            try
            {
                action();
                transaction.Commit();
            }
            catch (Exception)
            {
                transaction.Rollback();
                throw;
            }
        }

        public static void AutoDisposeDb(Action action)
        {
            var db = DataContextFactory.GetScopedDataContext<DbManager>((Type) null);
            try
            {
                action();
            }
            finally
            {
                db.Dispose();
            }
        }


        protected Transaction(DbManager dbManager)
        {
            _dbManager = dbManager;
        }

        public bool IsManaged
        {
            get
            {
                return _level == 0;
            }
        }

        public void Enter(IsolationLevel isolationLevel = defaultLevel)
        {
            _dbManager.BeginTransaction(isolationLevel);
            _level++;
        }

        public void Commit()
        {
            _dbManager.CommitTransaction();
            _level--;
        }

        public void Rollback()
        {
            _dbManager.RollbackTransaction();
            _level--;
        }

        

        protected DbManager _dbManager;
        protected int _level;
    }
}
